-
Notifications
You must be signed in to change notification settings - Fork 271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Bash Completion Support #99
Conversation
Hi @nickw444, thanks for the PR. I've had a look, but I'm still pondering some design/usability concerns.
I really like the hint approach, this could also be useful for eg. generating more useful help. Anyway, I'll have a bit more of a think about it, but at the moment I'm thinking that if 1. above is addressed, I'll probably just merge it because it's a great start, then if the underlying implementation changes it will be easy to do. |
Also, I think the hint methods could use some documentation. |
Hey @alecthomas thanks for the comments. I understand your concerns in all of your above points. 1. I've moved the "support" scripts into the Consider this: when distributing a package, (specifically a .deb), the package maintainer will usually add a Alternatively, package maintainers need to inform users that they can add additional lines to their
However, personally, I feel this isn't a great end user experience. Anyway, with that all being said, it's definitely the right way to go to move the scripts into kingpin, where a package maintainer can generate these scripts after compilation and add them to the distribution. 2. I originally felt that keeping completions outside of the app was the best idea, as it's more isolated and controlled (plus an easier feature IMO :P ), but, it didn't give users of kingpin great options for handling dynamic arguments without re-generating the script every time. A good example of such a use case is where you have a CLI tool which reads from an hosts file and provides completion of possible known hosts. By reaching into the application and performing a 3. I originally attempted this, and also implemented a hybrid, however due to how bash (and ZSH) handle completion selection, a space will always be added (unless there are multiple options to choose from). The original implementation I speak of would output every possible docs I've added documentation and tests. Let me know if you've got any additional comments :) |
34b62a5
to
02d3a22
Compare
The tests are failing, but once they're fixed up I'll take another look. Thanks! |
a.cmdGroup = newCmdGroup(a) | ||
a.HelpFlag = a.Flag("help", "Show context-sensitive help (also try --help-long and --help-man).") | ||
a.HelpFlag.Bool() | ||
a.Flag("help-long", "Generate long help.").Hidden().PreAction(a.generateLongHelp).Bool() | ||
a.Flag("help-man", "Generate a man page.").Hidden().PreAction(a.generateManPage).Bool() | ||
a.Flag("help-bash-completion", "Output possible completions for the given args.").Hidden().BoolVar(&a.completion) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd prefer this be named ---completion-bash
, as it has no real relationship to help.
That's a good point. Looking at the example completion code, it looks like it could be super powerful. Very nice.
That's a bummer, but good to know you had the same thought :) I think once you've addressed the few minor comments I made, this LGTM. |
eb85d0e
to
09e122d
Compare
I've made the requested modifications. I removed that However, I still can't get a green build. I've attempted using a relative package import, and not importing at all. What do you suggest I do to remediate this? |
The tests are failing because you're importing |
Apart from that, looks great, thanks! |
09e122d
to
2ca6c6a
Compare
Add Bash Completion Support. Many thanks to @nickw444 for doing this!
This is brilliant, thanks so much @nickw444. Much appreciated. |
Very nice, thank you @nickw444! |
Hey @alecthomas just wondering when you'll be building a release with these changes for gopkg.in? Cheers |
I just pushed out v2.1.11 |
Thanks! |
@nickw444 I've noticed that the command completion in particular seems inconsistent. _examples/curl doesn't seem to work at all. Any idea why? I haven't had time to look at it. |
I'll take a quick look now. |
I think I may have accidentally by chance found the issue you were having:
The shell will respond with completion that doesn't seem consistent with kingpin completion. This is because we didn't source the kingpin completion script. Run
|
I didn't see the first output, I saw no output, as you do with your last line. However, the curl example has commands and subcommands, which don't get completed. I'd expect:
|
I can reproduce this issue now. I'm sure this is because of the pattern being used to create this command line tool. Notice how the commands are instantiated from the kingpin library, rather than from an
All the flags work because they're defined on the command. Look at the completion example and how the commands are defined:
|
They're functionally equivalent though, so I'm not sure why that would make a difference? |
You're right about that. I'll take a look on Monday. Good find! |
👍 |
I've implemented deep bash completion integration within the library. Work towards #75. A bash completion script can call into any tool using Kingpin by using a new flag
--help-bash-completion
as the first argument, followed by subsequent user-entered arguments.Opening this PR to get some eyes on it, and see how it can be improved. Happy to add docs once we're happy with the overall structure of it (Since this does bring some new API):
type HintAction func(args []string) []string
A new typeHintAction
, a function that returns a list of options for completions.func (a *ArgClause) HintAction(action HintAction) *ArgClause
to register aHintAction
to call when completions are requested for an argument.func (a *ArgClause) HintOptions(options ...string) *ArgClause
to register a static slice of strings to provide as completions when requested. Internally registers aHintAction
that returns this slice.func (a *FlagClause) HintAction(action HintAction) *FlagClause
- Same as described forArgClause
func (a *FlagClause) HintOptions(options ...string) *FlagClause
- Same as described forArgClause
Additionally, FlagClause
EnumVar
will register all availableEnumVar
options as completion options too.Users will be presented with completion options for:
-
was the last user-entered argument)There's a bit of re-shuffling in this PR, including a new mixin (
cmdMixin
), due to some shared logic between theApplication
type and theCmdClause
type for autocompletionAdditionally, a lot of logic from
Application.execute
has been moved toApplication.Parse
to allow different code paths for bash completion / normal execution.An additional argument has been added to
Application.applyPreActions
to change whether or not sub commands should have preActions dispatched, since this causes issues with functionality such ashelp
, and--version
Included are two scripts
support/bash_completion
andsupport/zsh_completion
which should be modified and then sourced/installed by end users within their shells to enable bash completion.